<template>
  <Form :model="so" :label-width="60">
    <Row :gutter="20">
      <Col :span="6">
        <Form.Item label="服务器">
          <Select id="ecsId" v-model:value="so.nginx">
            <Select.Option v-for="(item, cIndex) in nginxs" :value="item">{{ item }}</Select.Option>
          </Select>
        </Form.Item>
      </Col>
      <Col :span="4">
        <Form.Item label="监控粒度">
          <Select v-model:value="so.interval" :options="intervals" />
        </Form.Item>
      </Col>
      <Col :span="4">
        <Form.Item label="聚合方式">
          <Select v-model:value="so.aggregate" :options="filters" />
        </Form.Item>
      </Col>
      <Col :span="6">
        <Form.Item label="时间">
          <DatePicker type="date" v-model:value="currentDate" format="YYYY-MM-DD" />
        </Form.Item>
      </Col>
      <Col :span="4" class="btn-group">
        <Button type="primary" shape="round" @click="RenderMetric"><SearchOutlined /> 查询</Button>
        <Button type="primary" danger @click="ClearDatas"><DeleteOutlined /> 清理数据</Button>
      </Col>
    </Row>
  </Form>
  <div ref="canvas" class="canvas"></div>
</template>

<script setup>
  import dayjs from 'dayjs';
  import * as echarts from 'echarts';

  import { useStore } from 'vuex';
  import { ref, reactive, inject, onMounted, nextTick } from 'vue';
  import { Form, Row, Col, Select, Button, DatePicker } from 'ant-design-vue';
  import { SearchOutlined, DeleteOutlined } from '@ant-design/icons-vue';

  const $store = useStore();
  const $http = inject('$http');
  const $modal = inject('$modal');
  const $message = inject('$message');
  const $eventBus = inject('$eventBus');

  const canvas = ref();
  const currentDate = ref(dayjs());
  const nginxs = reactive(['UAT', 'Production']);

  const intervals = reactive([
    { label: '实时', value: 60 },
    { label: '5分钟', value: 300 },
    { label: '10分钟', value: 600 },
    { label: '20分钟', value: 1200 },
    { label: '30分钟', value: 1800 },
    { label: '1小时', value: 3600 }
  ]);

  const filters = reactive([
    { label: '最大', value: 'max' },
    { label: '最小', value: 'min' },
    { label: '平均', value: 'avg' },
    { label: '求和', value: 'sum' },
    { label: '方差', value: 'std' }
  ]);

  const so = reactive({
    nginx: 'Production',
    interval: 300,
    aggregate: 'max'
  });

  let echartsInstance = null;
  const echartsMappings = [
    {
      title: 'HTTP请求数',
      prop: 'RequestInteval',
      yAxisIndex: 0
    },
    {
      title: '活跃的连接数量',
      prop: 'Connections',
      yAxisIndex: 1
    },
    {
      title: '读取客户端的连接数',
      prop: 'Reading',
      yAxisIndex: 1
    },
    {
      title: '响应数据到客户端的数量',
      prop: 'Writing',
      yAxisIndex: 1
    },
    {
      title: '驻留链接数',
      prop: 'Waiting',
      yAxisIndex: 1
    }
  ];

  const legendDatas = [];
  const seriesDatas = [];

  echartsMappings.forEach(m => {
    legendDatas.push(m.title);
    seriesDatas.push({
      name: m.title,
      type: 'line',
      smooth: true,
      yAxisIndex: m.yAxisIndex,
      data: []
    });
  });

  const echartsOption = {
    grid: {
      top: '60px',
      left: '50px',
      right: '50px',
      bottom: '25px'
    },
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        animation: false
      }
    },
    legend: {
      data: legendDatas
    },
    xAxis: {
      type: 'category',
      axisLabel: {
        formatter: '{value}'
      },
      data: []
    },
    yAxis: [
      {
        type: 'value',
        name: 'HTTP请求数',
        min: 0,
        position: 'left',
        axisLabel: {
          formatter: '{value}'
        }
      },
      {
        type: 'value',
        name: '连接/响应数量',
        position: 'right',
        axisLabel: {
          formatter: '{value}'
        }
      }
    ],
    series: seriesDatas
  };

  function ClearDatas() {
    $modal.confirm({
      title: '警告',
      content: '是否确定清理监控数据？',
      onOk() {
        $http.get('/api/monitor/clearDatas').then(res => {
          $message.success('清理成功！');

          RenderMetric();
        });
      }
    });
  }

  function RenderMetric() {
    if (!currentDate.value) {
      $message.warning('时间不能为空！');

      return;
    }

    $http.get(`/api/monitor/status/${so.aggregate}/${so.interval}?current=${dayjs(currentDate.value).format('YYYY-MM-DD')}`).then(rs => {
      echartsOption.xAxis.data = rs.datas.map(function (m) {
        return dayjs(m.RecordDateTime).format('YYYY-MM-DD HH:mm');
      });

      echartsMappings.forEach(m => {
        seriesDatas.find(s => s.name == m.title).data = rs.datas.map(function (d) {
          return d[m.prop];
        });
      });

      // 使用刚指定的配置项和数据显示图表。
      echartsInstance.setOption(echartsOption);
    });
  }

  function ResizeChartPanel(area) {
    if (canvas) {
      canvas.value.style.height = area.height - 93 + 'px';
    }

    if (echartsInstance) {
      echartsInstance.resize();
    }
  }

  onMounted(() => {
    nextTick(() => {
      echartsInstance = echarts.init(canvas.value);

      // 使用刚指定的配置项和数据显示图表。
      echartsInstance.setOption(echartsOption);

      RenderMetric();

      let area = $store.state.area.content;
      ResizeChartPanel(area);
    });

    $eventBus.on('windowResizeChanged', client => {
      ResizeChartPanel(client);
    });
  });
</script>

<style lang="less" scoped>
  .canvas {
    background: #fff;
    border-radius: 5px;
    padding: 5px;
    display: inline-block;
    width: 100%;
    height: 480px;
    margin-top: 10px;
  }
</style>
